<template>
    <label class="pe-checkbox" :class="[modelValue1 || modelValue.includes(value) ? 'pe-checkbox-active' : '', checkboxDisabled1 || disabledArr.includes(value) ? 'pe-checkbox-disabled' : '', sizeArr.includes(checkboxSize1) ? `pe-checkbox-${checkboxSize1}` : '',
    border ? 'pe-checkbox-border' : '', indeterminateValue ? 'pe-checkbox-indeterminate' : ''
    ]">
        <div class="pe-checkbox-item">
            <input v-if="typeof modelValue1 !== 'boolean'" class="pe-checkbox-inp" type="checkbox" v-model="modelValue" :name="checkboxName1"
                @change="onChange" :value="value" :disabled="checkboxDisabled1 || disabledArr.includes(value)">
            <input v-else class="pe-checkbox-inp" type="checkbox" v-model="modelValue1" :disabled="checkboxDisabled1"
                @change="onChange1" :name="checkboxName1">
            <div class="pe-checkbox-square">
                <svg v-if="!indeterminateValue" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024">
                    <path fill="currentColor"
                        d="M406.656 706.944 195.84 496.256a32 32 0 1 0-45.248 45.248l256 256 512-512a32 32 0 0 0-45.248-45.248L406.592 706.944z">
                    </path>
                </svg>
                <span v-else>-</span>
            </div>
        </div>
        <div v-if="label || useSlots().default" class="pe-checkbox-content">
            <slot>{{ label }}</slot>
        </div>
    </label>
</template>

<script setup lang="ts">
import { Ref, inject, ref, watch, useSlots, toRaw } from "vue"

const checkboxName: Ref<string> = inject("pe-checkbox-id", ref(""))
const modelValue: Ref<(string | number)[]> = inject("pe-checkbox-value", ref<(string | number)[]>([]))
const modelValue1 = defineModel<boolean>({ default: null })

/**
 * @param value 选中状态的值（只有在checkbox-group或者绑定对象类型为array时有效）
 * @param label 选中状态的值，只有在绑定对象类型为 array 时有效。
 * @param disabled 是否禁用
 * @param size Checkbox 的尺寸
 * @param border 是否显示边框
 * @param name 原生 name 属性
 * @param indeterminate 设置不确定状态，仅负责样式控制
 */
interface Props {
    value: string | number,
    label?: string | number,
    disabled?: boolean,
    size?: 'default' | 'small' | 'large'
    border?: boolean,
    name?: string,
    indeterminate?: boolean
}

const props = withDefaults(defineProps<Props>(), {
    disabled: false,
    size: 'default',
    border: false,
    indeterminate: false
})

const checkboxSize = inject("pe-checkbox-size", ref<'default' | 'small' | 'large'>())
const checkboxDisabled = inject("pe-checkbox-disabled", ref<boolean>(false))

const checkboxSize1 = ref<'default' | 'small' | 'large'>("default")
const checkboxDisabled1 = ref<boolean>(false)

const indeterminateValue = ref<boolean>(false)

const checkboxName1 = ref<string>("")

watch([props, checkboxSize, checkboxDisabled], ([newProps, newSize, newDisabled]) => {
    checkboxName1.value = checkboxName.value
    if (newSize) {
        checkboxSize1.value = newSize
    } else {
        checkboxSize1.value = newProps.size
    }
    if (newDisabled) {
        checkboxDisabled1.value = true
    } else {
        checkboxDisabled1.value = newProps.disabled
    }
    if (newProps.name) {
        checkboxName1.value = newProps.name
    }
    indeterminateValue.value = newProps.indeterminate
}, { immediate: true })

const emits = defineEmits(["change"])

// 禁用数组
const disabledArr: Ref<(number | string)[]> = inject("pe-checkbox-disabledArr", ref<(number | string)[]>([]))

// 绑定值改变时触发函数
const change = inject("pe-checkbox-change", Function, true)

const onChange = () => {
    change(toRaw(modelValue.value))
}

const onChange1 = (event: Event) => {
    const target: HTMLInputElement = event.target as HTMLInputElement
    if (target.checked) {
        indeterminateValue.value = false
    }
    emits("change", target.checked)
}

const sizeArr = ['small', 'large']
</script>

<script lang="ts">
export default {
    name: "pe-checkbox"
}
</script>